#include <YafridngInterface.h>

YafridngInterface::YafridngInterface(Ice::CommunicatorPtr& c)
{
  try
    {
      m_refListModel = Gtk::ListStore::create(columns);
      treeListModel = Gtk::ListStore::create(treeColumns);
      refXml = Gnome::Glade::Xml::create(GLADE_FILE);
      control = new Controller();
      communicator = c;

      Gtk::Window* main_win = 0;
      refXml->get_widget("YafridNG", main_win);
      main_win->set_title("YafridNG");
      Gtk::Label* animation = 0;
      refXml->get_widget("label5", animation);
      Gtk::Entry* initial = 0;
      Gtk::Entry* final = 0;
      Gtk::Image* header = 0;
      refXml->get_widget("header", header);
      header->set("./ui/pixmaps/header.png");
      
      refXml->get_widget("initialFrame", initial);
      refXml->get_widget("endFrame", final);
      initial->set_sensitive(false);
      final->set_sensitive(false);
      
      Gtk::TreeView* infoView = 0;
      refXml->get_widget("infoView", infoView);
      infoView->columns_autosize();
      infoView->set_model(treeListModel);
      infoView->append_column("Renderers", treeColumns.renderer);
      infoView->append_column("Status", treeColumns.status);

      //Display a progress bar instead of a decimal number:
      Gtk::CellRendererProgress* cell = new Gtk::CellRendererProgress;
      int cols_count = infoView->append_column("P2P progress", *cell);
      Gtk::TreeViewColumn* pColumn = infoView->get_column(cols_count - 1);
      if(pColumn)
	{
#ifdef GLIBMM_PROPERTIES_ENABLED
	  pColumn->add_attribute(cell->property_value(), treeColumns.p2p);
#else
	  pColumn->add_attribute(*cell, "value", treeColumns.p2p);
#endif
	}

      //infoView->append_column("P2P", treeColumns.p2p);
      infoView->append_column("Work Units", treeColumns.wu);
      
      Gtk::Statusbar* status = 0;
      refXml->get_widget("statusBar", status);
      status->push("Stopped");
      Gtk::Button* launchButton = 0;
      refXml->get_widget("launchButton", launchButton);
      if(launchButton)
	{
	  launchButton->signal_clicked().connect(sigc::mem_fun(*this, &YafridngInterface::launchButton_clicked_cb));
	}

      Gtk::Button* cancelButton = 0;
      refXml->get_widget("cancelButton", cancelButton);
      if(cancelButton)
	{
	  cancelButton->signal_clicked().connect(sigc::mem_fun(*this, &YafridngInterface::cancelButton_clicked_cb));
	}
      Gtk::ComboBox* combo = 0;
      refXml->get_widget("piecesCombo", combo);
      combo->set_model(m_refListModel);
      
      Gtk::RadioButton* radio = 0;
      refXml->get_widget("staticButton", radio);
      if(radio)
	{
	  radio->signal_toggled().connect(sigc::mem_fun(*this, &YafridngInterface::radioButton_changed_cb));
	}
      
      //Adding Elements to combo
      Gtk::TreeModel::Row row = *(m_refListModel->append());
      row[columns.m_col_text] = 4;
      row[columns.m_col_number] = 2;
      row = *(m_refListModel->append());
      row[columns.m_col_text] = 9;
      row[columns.m_col_number] = 3;
      row = *(m_refListModel->append());
      row[columns.m_col_text] = 16;
      row[columns.m_col_number] = 4;
      row = *(m_refListModel->append());
      row[columns.m_col_text] = 25;
      row[columns.m_col_number] = 5;
      Gtk::TreeModel::Children childs(m_refListModel->children());
      combo->set_active(childs.begin());
    }
  catch(const Gnome::Glade::XmlError& ex)
    {
      std::cerr << ex.what() << std::endl;
    }
}

Gtk::Window* YafridngInterface::getMainWindow()
{
  Gtk::Window* main_win = 0;
  refXml->get_widget("YafridNG", main_win);
  return main_win;
}

void YafridngInterface::radioButton_changed_cb()
{
  Gtk::RadioButton* radio = 0;
  refXml->get_widget("staticButton", radio);
  Gtk::Entry* initial = 0;
  Gtk::Entry* final = 0;
  refXml->get_widget("initialFrame", initial);
  refXml->get_widget("endFrame", final);
  Gtk::ComboBox* combo = 0;
  refXml->get_widget("piecesCombo", combo);
  Gtk::Label* frame = 0;
  Gtk::Label* animation = 0;
  refXml->get_widget("label4", frame);
  refXml->get_widget("label5", animation);
  if(radio->get_active())
    {
      initial->set_sensitive(false);
      final->set_sensitive(false);
      combo->set_sensitive(true);
      frame->set_sensitive(true);
    }
  else
    {
      initial->set_sensitive(true);
      final->set_sensitive(true);
      combo->set_sensitive(false);
      frame->set_sensitive(false);
    }
}
void YafridngInterface::launchButton_clicked_cb()
{
  FILE* fp;
  char temp[STRLEN];
  int timeout = 1500;
  Gtk::FileChooserButton* fc = 0;
  refXml->get_widget("filePath", fc);
  Gtk::Statusbar* status = 0;
  refXml->get_widget("statusBar", status);
  
  if(fc){
    string file = fc ->get_filename();
    if(file == ""){
      Gtk::MessageDialog advice("You should choose a file for rendering");
      advice.set_title("Error Message");
      advice.run();
    }
    
    else{
      appInfo info;
      info.fileName = file;
      string command = "blender " + info.fileName + " -b -P getRes.py";
      //Obtainig resolution of the scene
      system(command.c_str());
      fp = fopen("scene.txt", "r");
      fgets(temp, STRLEN, fp);
      info.renderEngine = atoi(temp);
      fgets(temp, STRLEN, fp);
      info.width = atoi(temp);
      fgets(temp, STRLEN, fp);
      info.height = atoi(temp);
      fclose(fp);

      info.renderers = 16;
      info.transferSize = 1000*1024;

      Gtk::RadioButton* radio = 0;
      refXml->get_widget("staticButton", radio);
      //Cleaning the view
      treeListModel->clear();
      //Scene is a static frame
      if(radio->get_active()){
	Gtk::ComboBox* combo = 0;
	refXml->get_widget("piecesCombo", combo);
	Gtk::TreeModel::iterator iter = combo->get_active();
	Gtk::TreeModel::Row row = *iter;
	if(iter){
	  int id = row[columns.m_col_number];
	  info.sceneType = SCENE;
	  info.nZones = id;
	  status->pop();
	  status->push("Rendering Static Frame");
	  Gtk::Button* launchButton = 0;
	  refXml->get_widget("launchButton", launchButton);
	  launchButton->set_sensitive(false);
	  ClientThreadPtr client = new ClientThread(info, control, communicator);
	  client->start();
	  sigc::slot<bool> my_slot = sigc::bind(sigc::mem_fun(*this, &YafridngInterface::updateFunction), SCENE);
	  sigc::connection conn = Glib::signal_timeout().connect(my_slot, timeout);
	}
      }
      //Scene is an animation
      else{
	Gtk::Entry* initialFrame = 0;
	Gtk::Entry* endFrame = 0;
	refXml->get_widget("initialFrame", initialFrame);
	refXml->get_widget("endFrame", endFrame);
	info.sceneType = ANIMATION;
	info.startFrame = atoi((initialFrame->get_text()).c_str());
	info.endFrame = atoi((endFrame->get_text()).c_str());
	status->pop();
	status->push("Rendering Animation");
	Gtk::Button* launchButton = 0;
	refXml->get_widget("launchButton", launchButton);
	launchButton->set_sensitive(false);
	client = new ClientThread(info, control, communicator);
	client->start();
	sigc::slot<bool> my_slot = sigc::bind(sigc::mem_fun(*this, &YafridngInterface::updateFunction), ANIMATION);
	sigc::connection conn = Glib::signal_timeout().connect(my_slot, timeout);
      }
    }
  }
}

void YafridngInterface::cancelButton_clicked_cb()
{
  Gtk::Window* main = 0;
  refXml->get_widget("YafridNG", main);
  Gtk::Window* imageWindow = 0;
  refXml->get_widget("imageWindow", imageWindow);
  imageWindow->hide();
  main->hide();
}
bool YafridngInterface::updateFunction(int sceneType)
{    
  bool finished = control->getFinished();
  
  vector<info> renderers = control->getRenderers();
  Gtk::TreeView* infoView = 0;
  refXml->get_widget("infoView", infoView);
  Gtk::TreeModel::Children childs(treeListModel->children());
  bool exists = false;
  for(int i = 0; i < renderers.size(); i++){
    for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); iter++){
      Gtk::TreeModel::Row row = *iter;
      string rtemp = row[treeColumns.renderer];
      if(rtemp == renderers.at(i).renderer){
	row[treeColumns.status] = renderers.at(i).status;
	row[treeColumns.p2p] = renderers.at(i).p2p;
	row[treeColumns.wu] = renderers.at(i).workUnit;
	exists = true;
      }
    }
    if(!exists){
      Gtk::TreeModel::iterator it = treeListModel->append();
      Gtk::TreeModel::Row row = *it;
      row[treeColumns.renderer] = renderers.at(i).renderer;
      row[treeColumns.status] = renderers.at(i).status;
      row[treeColumns.p2p] = renderers.at(i).p2p;
      row[treeColumns.wu] = renderers.at(i).workUnit;
    }
    exists = false;
  }

  if(finished){
    control->reset();
    Gtk::Statusbar* status = 0;
    refXml->get_widget("statusBar", status);
    status->pop();
    status->push("Stopped");
    Gtk::Button* launchButton = 0;
    refXml->get_widget("launchButton", launchButton);
    launchButton->set_sensitive(true);
    return false;
  }
  
  if(sceneType == SCENE){
    string image = control->getImage();
    if(image != "")
      {
	Gtk::Image* resultImage = 0;
	Gtk::Window* imageWindow = 0;
	refXml->get_widget("resultImage", resultImage);	
	resultImage->set(image);
	refXml->get_widget("imageWindow", imageWindow);
	imageWindow->set_title("YafridNG - Preview");
	imageWindow->show();
      }
  }

  else
    return true;

  return true;
}

YafridngInterface::~YafridngInterface()
{
}
